module ActiveTest::Behaviour
  module Authentication
    
    def self.included(base)
      base.extend(ClassMethods)
    end
    
    module ClassMethods
      # Generates a test case which checks a given action requires a user to be logged in.
      # This is a negative test case.
      #
      # Options:
      # * +:parameters+ -- a hash of parameters to be passed as part of the request.
      #
      def requires_login_on(action, options = {})
        define_behavioral(:require_login_on, action, options) do
          logout
          assert_requires_login { send("call_#{action}_action", options) }
        end
      end
      
      # Generates a test case whcih checks a given action accepts the current user.
      # This is a positive test case.
      #
      # Options:
      # * +:parameters+ -- a hash of parameters to be passed as part of the request.
      # * +:login_as+ -- user to login as for this test case (takes a symbol)
      #
      def accepts_login_on(action, options = {})
        define_behavioral(:accept_login_on, action, options) do
          login_as(options[:login_as]) if options[:login_as]
          assert_accepts_login { send("call_#{action}_action", options) }
        end
      end
    end

    # Sets the current user in the session from the user fixtures.
    def login_as(user)
      @controller.instance_variable_set("@current_user", users(user))
    end

    # Sets the current_user in the session to nil.
    def logout
      @controller.instance_variable_set("@current_user", nil)
    end

  end
end